import { useCallback, useEffect, useState } from 'react';
import { Typography } from 'antd';
import Cookies from 'js-cookie';
import DataTable from './components/DataTable';
import DataTree, { updateTreeData } from './components/DataTree';
import SearchBar from './components/SearchBar';
import service from './service';
import {
  calcTableScrollHeight,
  decorateKey,
  decorateRowKey,
  getMemberIconByKey,
  getLowercase,
} from './utils';
import { DEFAULT_PAGE_SIZE, PREFIX } from './utils/consts';
import { getMessage } from '@inbiz/react';
import { renderCellText } from './utils/tableUtil';
const { Text } = Typography;

export default function UserTab(props: any) {
  const [departmentTreeData, setDepartmentTreeData] = useState<any[]>([]);
  const [selectedKeys, _selectedKeys] = useState<string[]>([]);
  const [expandedKeys, _expandedKeys] = useState<string[]>([]);
  const [pageNum, _pageNum] = useState(1);
  const [pageSize, _pageSize] = useState(props.pageSize || DEFAULT_PAGE_SIZE);
  const [isChild, _isChild] = useState(true);
  const [total, _total] = useState(0);
  const [searchValue, _searchValue] = useState('');
  const [data, _data] = useState<any[]>([]);
  const [hasMore, _hasMore] = useState(true);
  const [loadingMore, _loadingMore] = useState(false);
  const {
    selectedRowKeys,
    multiple,
    uniqueTabs,
    setSelected,
    tabKey,
    height,
    topDepartmentIds,
    mode,
    isUnique,
    forbiddenItems,
    collectivization,
    configEvents,
    departmentFilteringRules,
  } = props;

  const {
    getTopDepartmentList,
    getDepartmentList,
    getSubDepartmentList,
  } = service;

  const _getTopDepartmentList = useCallback(async (params: object) => {
    const newParams = (await configEvents.current?.onGetTopDepartmentsParams?.(params)) || params;
    const data = await (configEvents.current?.onGetTopDepartmentsRequest || getTopDepartmentList)(newParams as any);
    return await configEvents.current?.onGetTopDepartsmentData?.(data) || data;
  }, []);

  const _getDepartmentList = useCallback(async (params: object) => {
    const newParams = (await configEvents.current?.onGetDepartmentsParams?.(params)) || params;
    const data = await (configEvents.current?.onGetDepartmentsRequest || getDepartmentList)(newParams as any);
    return await configEvents.current?.onGetDepartmentsData?.(data) || data;
  }, []);

  const _getSubDepartmentList = useCallback(async (params: object) => {
    const newParams = (await configEvents.current?.onGetSubDepartmentsParams?.(params)) || params;
    const data = await (configEvents.current?.onGetSubDepartmentsRequest || getSubDepartmentList)(newParams as any);
    return await configEvents.current?.onGetSubDepartmentsData?.(data) || data;
  }, []);

  const decorateData = decorateKey(tabKey, (data) => {
    return {
      icon: getMemberIconByKey(tabKey, forbiddenItems.includes(data.id)),
    };
  });

  const rowKey = decorateRowKey(tabKey);

  const getDeptId = (selKeys?: string[]) => {
    let keys = selKeys || selectedKeys;
    if (keys.length) {
      let key = keys[0];
      const [tabKey, deptId] = key.split('-');
      if (deptId) {
        return Number(deptId);
      }
    }
  };

  const onSearch = (value: string, checked: boolean) => {
    _searchValue(value);
    _isChild(checked);
    _getDepartmentList({
      departmentId: getDeptId() as number,
      searchContent: value,
      isChild: checked,
      pageNum: 1,
      pageSize: pageSize,
      isContainSelf: collectivization ? true : topDepartmentIds.includes(getDeptId()),
    })
      .then((res) => {
        if (res.Info) {
          _data((getLowercase(res.Info, tabKey) || []).map(decorateData));
          _pageNum(1);
          _total(res.Total);
        }
      });
  };

  const onPagination = (pagination: { current: number; pageSize: number }) => {
    _getDepartmentList({
      departmentId: getDeptId() as number,
      searchContent: searchValue,
      isChild: isChild,
      pageNum: pagination.current,
      pageSize: pagination.pageSize,
      isContainSelf: collectivization ? true : topDepartmentIds.includes(getDeptId()),
    })
      .then((res) => {
        if (res.Info) {
          _data((getLowercase(res.Info, tabKey) || []).map(decorateData));
          _pageNum(pagination.current);
          _pageSize(pagination.pageSize);
          _total(res.Total);
        }
      });
  };

  const onSelect = (keys) => {
    if (keys.length) {
      _selectedKeys(keys);
      const deptId = getDeptId(keys);
      if (deptId) {
        _getDepartmentList({
          departmentId: deptId,
          searchContent: searchValue,
          isChild: isChild,
          pageNum: 1,
          pageSize: pageSize,
          isContainSelf: collectivization ? true : topDepartmentIds.includes(deptId),
        })
          .then((res) => {
            if (res.Info) {
              _data((getLowercase(res.Info, tabKey) || []).map(decorateData));
              _pageNum(1);
              _total(res.Total);
            }
          });
      }
    }
  };

  useEffect(() => {
    if (departmentFilteringRules != 'exceptSelected' || departmentFilteringRules == 'exceptSelected' && topDepartmentIds?.length == 1 && topDepartmentIds?.[0] == 1 || departmentFilteringRules == 'exceptSelected' && topDepartmentIds?.length == 0 || collectivization) {
      _getTopDepartmentList({
        departmentIds: collectivization
          ? Cookies.get('orgIdentityId')
            ? [Cookies.get('orgIdentityId')]
            : [1]
          : departmentFilteringRules == 'exceptSelected' && topDepartmentIds?.length == 1 && topDepartmentIds?.[0] == 1 ? [] : departmentFilteringRules != 'exceptSelected' && topDepartmentIds?.length == 0 ? [1] : departmentFilteringRules == 'exceptSelected' && topDepartmentIds?.length == 0 ? [1] : topDepartmentIds,
      })
        .then((res) => {
          if (Array.isArray(res) && res.length) {
            const keys = [decorateData(getLowercase(res, tabKey)[0]).key];
            _selectedKeys(keys);
            _expandedKeys(keys);
            setDepartmentTreeData(getLowercase(res, tabKey).map(decorateData));
            service
              .getDepartmentList({
                departmentId: getDeptId(keys) as number,
                searchContent: '',
                isChild: true,
                pageNum: 1,
                pageSize: pageSize,
                isContainSelf: true,
              })
              .then((res) => {
                if (res.Info) {
                  _data((getLowercase(res.Info, tabKey) || []).map(decorateData));
                  _pageNum(1);
                  _total(res.Total);
                }
              });
          }
        });
    } else {
      _getSubDepartmentList({
        departmentId: 1,
        banDeptIds: topDepartmentIds,
      }).then((res) => {
        if (Array.isArray(res) && res.length) {
          const keys = [decorateData(getLowercase(res, tabKey)[0]).key];
          _selectedKeys(keys);
          _expandedKeys(keys);
          setDepartmentTreeData(getLowercase(res, tabKey).map(decorateData));
          service
            .getDepartmentList({
              departmentId: getDeptId(keys) as number,
              searchContent: '',
              isChild: true,
              pageNum: 1,
              pageSize: pageSize,
              isContainSelf: true,
            })
            .then((res) => {
              if (res.Info) {
                _data((getLowercase(res.Info, tabKey) || []).map(decorateData));
                _pageNum(1);
                _total(res.Total);
              }
            });
        }
      })
    }
  }, [departmentFilteringRules]);

  const renderTree = useCallback(
    (config?: { checkable: boolean; checkedKeys: string[]; onCheck: (...args) => void }) => {
      return (
        <DataTree
          showIcon
          checkedKeys={config?.checkedKeys}
          checkable={config?.checkable}
          onCheck={config?.onCheck}
          expandedKeys={expandedKeys}
          onExpand={(keys) => _expandedKeys(keys)}
          treeData={departmentTreeData}
          loadData={(e) => {
            return _getSubDepartmentList({
              departmentId: e.identityid,
              id: e.id,
            })
              .then((res) => {
                if (res) {
                  setDepartmentTreeData((list) => {
                    return updateTreeData(list, e.key, getLowercase(res, tabKey).map(decorateData));
                  });
                }
              });
          }}
          multiple={false}
          selectedKeys={selectedKeys}
          onSelect={onSelect}
        />
      );
    },
    [selectedKeys, onSelect, expandedKeys, departmentTreeData],
  );

  return (
    <div className={`${PREFIX}-tab`} style={{ margin: uniqueTabs ? '10px 20px' : '' }}>
      {mode == 'tree' ? (
        <div className={`${PREFIX}-treeModeWrap`}>
          {renderTree({
            checkable: true,
            checkedKeys: selectedRowKeys,
            onCheck: (keys, target) => {
              const { checked, checkedNodes } = target;
              setSelected(checkedNodes);
            },
          })}
        </div>
      ) : (
        <div style={{ height: uniqueTabs ? height : '100%' }}>
          <div className={`${PREFIX}-leftTree`}>{renderTree()}</div>
          <div className={`${PREFIX}-rightContent`}>
            <SearchBar
              // 包含子部门
              checkLabel={getMessage('MemberSelect.lang.includingSubDepart')}
              // 输入部门名称
              placeholder={getMessage('MemberSelect.lang.enterDepartName')}
              defaultChecked={isChild}
              defaultValue={searchValue}
              onSearch={onSearch}
            />
            <DataTable
              rowSelection={{
                hideSelectAll: isUnique,
                getCheckboxProps: (r) => {
                  return {
                    disabled: forbiddenItems.includes(r.id),
                  };
                },
              }}
              multiple={multiple}
              rowKey={rowKey}
              scroll={{
                scrollToFirstRowOnChange: true,
                y: calcTableScrollHeight(height, true),
              }}
              onRow={(item, index) => {
                return {
                  onClick: (e) => {
                    e.currentTarget
                      .querySelector(multiple ? '.ant-checkbox-wrapper' : '.ant-radio-wrapper')
                      ?.click();
                    props.onRowClick?.(item, index);
                  },
                };
              }}
              rowClassName={(r) => {
                if (forbiddenItems.includes(r.id)) {
                  return 'datatable-forbidden-item';
                } else {
                  return '';
                }
              }}
              pagination={{
                pageSize,
                current: pageNum,
                total,
              }}
              columns={[
                {
                  // 部门名称
                  title: <Text ellipsis={{ tooltip: true }}>{getMessage('MemberSelect.lang.departName')}</Text>,
                  dataIndex: 'name',
                  key: 'name',
                  render: renderCellText('name', true),
                },
                {
                  // 部门
                  title: <Text ellipsis={{ tooltip: true }}>{getMessage('MemberSelect.lang.personTabs.department')}</Text>,
                  dataIndex: 'deptpathname',
                  key: 'deptpathname',
                  render: renderCellText('deptpathname', true),
                },
              ]}
              dataSource={data}
              onChange={onPagination}
              selectedRowKeys={selectedRowKeys}
              onSelectChange={(keys, rows) => {
                setSelected(keys, data);
              }}
            />
          </div>
        </div>
      )}
    </div>
  );
}